package com.xhxi.photobooker.websocket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhxi.photobooker.constant.JwtClaimsConstant;
import com.xhxi.photobooker.properties.JwtProperties;
import com.xhxi.photobooker.utils.JwtUtil;
import com.xhxi.photobooker.utils.MessageUtils;
import com.xhxi.photobooker.websocket.pojo.Message;
import io.jsonwebtoken.Claims;
import jakarta.annotation.PostConstruct;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.xhxi.photobooker.service.MessageService;
import com.xhxi.photobooker.websocket.SpringContextHolder;

@ServerEndpoint(value = "/chat")
@Component
public class ChatEndpoint {

    // 保存在线的用户，key为用户名，value为 Session 对象
    private static final Map<String, Session> onlineUsers = new ConcurrentHashMap<>();

    // 移除静态变量和注入相关内容
    // private static String jwtSecret;
    // @Autowired
    // private JwtProperties jwtProperties;
    // @PostConstruct
    // public void init() {
    //     jwtSecret = jwtProperties.getUserSecretKey();
    // }

    /**
     * 建立websocket连接后，被调用
     *
     * @param session Session
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        System.out.println("[WebSocket] onOpen 被调用! Session ID: " + session.getId());
        System.out.println("[WebSocket] 请求参数: " + session.getRequestParameterMap());
        
        try {
            // 检查token参数是否存在
            var tokenParams = session.getRequestParameterMap().get("token");
            if (tokenParams == null || tokenParams.isEmpty()) {
                System.err.println("[WebSocket] token参数不存在");
                session.close();
                return;
            }
            
            String token = tokenParams.get(0);
            System.out.println("[WebSocket] token: " + token);
            
            if (token == null || token.trim().isEmpty()) {
                System.err.println("[WebSocket] token为空");
                session.close();
                return;
            }

            // 动态获取jwtSecret
            com.xhxi.photobooker.properties.JwtProperties jwtProperties = com.xhxi.photobooker.websocket.SpringContextHolder.getBean(com.xhxi.photobooker.properties.JwtProperties.class);
            String jwtSecret = jwtProperties.getUserSecretKey();
            System.out.println("[WebSocket] jwtSecret: " + jwtSecret);

            io.jsonwebtoken.Claims claims = com.xhxi.photobooker.utils.JwtUtil.parseJWT(jwtSecret, token);
            System.out.println("[WebSocket] claims: " + claims);

            // 从JWT中获取用户名（存储在subject中）和用户ID
            String username = claims.getSubject(); // 用户名存储在subject中
            Long userId = claims.get("userId", Long.class); // 用户ID存储在claims中
            System.out.println("[WebSocket] 解析结果 - username: " + username + ", userId: " + userId);
            
            if (username == null || userId == null) {
                System.err.println("[WebSocket] username or userId is null, closing session");
                session.close();
                return;
            }
            
            onlineUsers.put(String.valueOf(userId), session);
            session.getUserProperties().put(com.xhxi.photobooker.constant.JwtClaimsConstant.USERNAME, username);
            session.getUserProperties().put(com.xhxi.photobooker.constant.JwtClaimsConstant.USER_ID, userId);
            session.getUserProperties().put("claims", claims); // 存claims

            System.out.println("[WebSocket] 用户 " + username + " (ID: " + userId + ") 连接成功");
            System.out.println("[WebSocket] 当前在线用户数: " + onlineUsers.size());

            // 通知所有用户，当前用户上线了
            String message = com.xhxi.photobooker.utils.MessageUtils.getMessage(true, null, getFriends());
            broadcastAllUsers(message);
        } catch (Exception e) {
            System.err.println("[WebSocket] onOpen error: " + e.getMessage());
            e.printStackTrace();
            try { session.close(); } catch (IOException ex) { ex.printStackTrace(); }
        }
    }


    private Set<String> getFriends() {
        return onlineUsers.keySet();
    }

    //广播消息
    private void broadcastAllUsers(String message) {
        try {
            Set<Map.Entry<String, Session>> entries = onlineUsers.entrySet();

            for (Map.Entry<String, Session> entry : entries) {
                // 获取到所有用户对应的 session 对象
                Session session = entry.getValue();

                // 使用 getBasicRemote() 方法发送同步消息
                session.getBasicRemote().sendText(message);
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    /**
     * 浏览器发送消息到服务端时该方法会被调用，也就是私聊
     * 张三  -->  李四
     *
     * @param message String
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            JSONObject json = JSON.parseObject(message);
            Long toId = json.getLong("toId");
            String toRole = json.getString("toRole");
            Long orderId = json.getLong("orderId");
            String sessionId = json.getString("sessionId");
            String type = json.getString("type");
            String content = json.getString("content");
            String fileUrl = json.getString("fileUrl");

            Claims claims = (Claims) session.getUserProperties().get("claims");
            if (claims == null) {
                System.err.println("[WebSocket] claims is null, cannot process message");
                return;
            }
            Long senderId = claims.get("userId", Long.class);
            String senderRole = claims.get("role", String.class);
            String currentUser = (String) session.getUserProperties().get("username");

            // 兜底：senderRole/receiverRole不能为空
            if (senderRole == null || senderRole.isEmpty()) senderRole = "user";
            if (toRole == null || toRole.isEmpty()) toRole = "photographer";

            // 推送消息：用toId查找对方session
            Session toSession = onlineUsers.get(String.valueOf(toId));
            String messageToSend = MessageUtils.getMessage(false, currentUser, content);
            if (toSession != null) {
                toSession.getBasicRemote().sendText(messageToSend);
            }

            // 自动落库
            MessageService messageService = SpringContextHolder.getBean(MessageService.class);
            com.xhxi.photobooker.entity.Message entityMsg = new com.xhxi.photobooker.entity.Message();
            entityMsg.setSenderId(senderId);
            entityMsg.setSenderRole(senderRole);
            entityMsg.setReceiverId(toId);
            entityMsg.setReceiverRole(toRole);
            entityMsg.setOrderId(orderId);
            entityMsg.setSessionId(sessionId);
            entityMsg.setType(type);
            entityMsg.setContent(content);
            entityMsg.setFileUrl(fileUrl);
            entityMsg.setCreateTime(new java.util.Date());
            messageService.saveMessage(entityMsg);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    /**
     * 断开 websocket 连接时被调用
     *
     * @param session Session
     */
    @OnClose
    public void onClose(Session session) throws IOException {
        String user = (String) session.getUserProperties().get("username");
        if (user != null) {
            Session remove = onlineUsers.remove(user);
            if (remove != null) {
                remove.close();
            }
            session.close();
        }
        String message = MessageUtils.getMessage(true, null, getFriends());
        broadcastAllUsers(message);
    }

}